package com.arm.tools;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {

	/**
	 * 日期格式： yyyyMM
	 **/
	public static final String DATE_TIME_YYYYMM = "yyyyMM";
	/**
	 * 日期格式： yyyy-MM
	 **/
	public static final String DATE_TIME_YYYY_MM = "yyyy-MM";
	/**
	 * 日期格式： MMdd
	 **/
	public static final String DATE_TIME_MMdd = "MMdd";
	/**
	 * 日期格式： yyyy-MM-dd HH:mm:ss
	 **/
	public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
	/**
	 * 日期格式： yyy-MM-dd HH:mm
	 **/
	public static final String DATE_TIME_NO_SS = "yyyy-MM-dd HH:mm";
	/**
	 * 日期格式：yyyyMMddHHmmss
	 **/
	public static final String DATE_TIME_NO = "yyyyMMddHHmmss";
	/**
	 * 日期格式：yyyy-MM-dd
	 **/
	public static final String DATE = "yyyy-MM-dd";
	/**
	 * 日期格式：dd/MM/yyyy
	 **/
	public static final String DATE2 = "dd/MM/yyyy";
	/**
	 * 日期格式：yyyyMMdd
	 **/
	public static final String DATE3 = "yyyyMMdd";
	/**
	 * 日期格式： MM月dd日
	 **/
	public static final String DATE4 = "MM月dd日";
	/**
	 * 日期格式：yyyy年MM月dd日 HH:mm:ss
	 **/
	public static final String DATE5 = "yyyy年MM月dd日 HH:mm:ss";
	/**
	 * HHmmss
	 **/
	public static final String TIME_HHmmss = "HHmmss";
	/**
	 * HH:mm:ss
	 **/
	public static final String TIME = "HH:mm:ss";
	/**
	 * HH:mm
	 **/
	public static final String TIME2 = "HH:mm";
	private static final String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
	/**
	 * 有关日期工具类(extends TimeUtil)
	 * 
	 * TimeUtil主要功能有： 1.各种日期类型（字符，util.Date，sql.Date，Calendar等）转换
	 * 2.获取指定日期的年份，月份，日份，小时，分，秒，毫秒 3.获取当前/系统日期(指定日期格式) 4.获取字符日期一个月的天数
	 * 5.获取指定月份的第一天,最后一天
	 * 
	 * DateUtil主要功能有： 1.日期比较 2.获取2个字符日期的天数差，周数差，月数差，年数差 3.日期添加 4.判断给定日期是不是润年
	 */

	// ---当前日期的年，月，日，时，分，秒
	public static Calendar now = Calendar.getInstance();
	int year = now.get(Calendar.YEAR);
	int date = now.get(Calendar.DAY_OF_MONTH);
	int month = now.get(Calendar.MONTH) + 1;
	int hour = now.get(Calendar.HOUR);
	int min = now.get(Calendar.MINUTE);
	int sec = now.get(Calendar.SECOND);

	/**
	 * 获取一个月的天数
	 * 
	 * @return
	 */
	public static Integer getDaysForMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		Integer maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		return maxDay;
	}

	/**
	 * 获取一个月的最后一天
	 * 
	 * @return
	 */
	public static Date getLastDayForMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		Integer maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		cal.set(Calendar.DAY_OF_MONTH, maxDay);
		return cal.getTime();
	}

	/**
	 * 获取一个月的第一天
	 * 
	 * @return
	 */
	public static Date getFirstDayForMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		cal.set(Calendar.DAY_OF_MONTH, 1);
		return cal.getTime();
	}

	/**
	 * 将短时间格式时间转换为字符串 yyyy-MM-dd
	 * 
	 * @param dateDate
	 * @return
	 */
	public static String dateToStr(Date dateDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(dateDate);
		return dateString;
	}

	/**
	 * 格式化时间
	 * 
	 * @param date
	 * @param format
	 *            格式化样式
	 * @return
	 */
	public static String dateToStr(Date date, String format) {
		if (null == date) {
			return null;
		}
		SimpleDateFormat sformat = new SimpleDateFormat(format);
		return sformat.format(date);
	}

	/**
	 * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
	 * 
	 * @param dateDate
	 * @return
	 */
	public static String dateToStrLong(Date dateDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = formatter.format(dateDate);
		return dateString;
	}

	/**
	 * 字符串转换成日期
	 * 
	 * @param str
	 * @return date
	 */
	public static Date strToDate(String str) {
		if (str == null || "".equals(str))
			return null;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = format.parse(str);
		} catch (ParseException e) {
			format = new SimpleDateFormat("yyyy-MM-dd");
			try {
				date = format.parse(str);
			} catch (ParseException e1) {
				try {
					date = format.parse(str);
				} catch (ParseException e2) {
					System.out.println("转化时间格式异常:" + str);
				}
			}
		}
		return date;
	}

	/**
	 * 字符串转换成日期
	 * 
	 * @param str
	 * @return date
	 */
	public static Date strToDate(String str, String dataFormat) {

		if (str == null || "".equals(str))
			return null;
		SimpleDateFormat format = new SimpleDateFormat(dataFormat);
		Date date = null;
		try {
			date = format.parse(str);
		} catch (ParseException e) {
			System.out.println("字符串转换成日期异常:" + str);
		}
		return date;
	}

	/**
	 * util.Date型日期转化指定格式的字符串型日期
	 * 
	 * @param p_utilDate
	 *            Date
	 * @param p_format
	 *            String 格式1:"yyyy-MM-dd" 格式2:"yyyy-MM-dd hh:mm:ss EE"
	 *            格式3:"yyyy年MM月dd日 hh:mm:ss EE" 说明: 年-月-日 时:分:秒 星期 注意MM/mm大小写
	 * @return String
	 * @Author:
	 * @Date: 2006-10-31
	 */
	public static String toStrDateFromUtilDateByFormat(Date p_utilDate, String p_format)
			throws ParseException {
		String l_result = "";
		if (p_utilDate != null) {
			SimpleDateFormat sdf = new SimpleDateFormat(p_format);
			l_result = sdf.format(p_utilDate);
		}
		return l_result;
	}

	// -----------------获取指定日期的年份，月份，日份，小时，分，秒，毫秒----------------------------
	/**
	 * 获取指定日期的年份
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return int 年份
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static int getYearOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.get(Calendar.YEAR);
	}

	/**
	 * 获取指定日期的月份
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return int 月份
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static int getMonthOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.get(Calendar.MONTH) + 1;
	}

	/**
	 * 获取指定日期的日份
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return int 日份
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static int getDayOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	public static int getLastDayOfMonth(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取指定日期的小时
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return int 日份
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static int getHourOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取指定日期的分钟
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return int 分钟
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static int getMinuteOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.get(Calendar.MINUTE);
	}

	/**
	 * 获取指定日期的秒钟
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return int 秒钟
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static int getSecondOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.get(Calendar.SECOND);
	}

	/**
	 * 获取指定日期的毫秒
	 * 
	 * @param p_date
	 *            util.Date日期
	 * @return long 毫秒
	 * @author zhuqx
	 * @Date: 2006-10-31
	 */
	public static long getMillisOfDate(Date p_date) {
		Calendar c = Calendar.getInstance();
		c.setTime(p_date);
		return c.getTimeInMillis();
	}

	/**
	 * 在给定的日期基础上添加年，月，日、时，分，秒 例如要再2006－10－21（uitl日期）添加3个月，并且格式化为yyyy-MM-dd格式，
	 * 这里调用的方式为 addDate(2006－10－21,3,Calendar.MONTH,"yyyy-MM-dd")
	 * 
	 * @param p_startDate
	 *            给定的日期
	 * @param p_count
	 *            时间的数量
	 * @param p_field
	 *            添加的域
	 * @param p_format
	 *            时间转化格式，例如：yyyy-MM-dd hh:mm:ss 或者yyyy-mm-dd等
	 * @return 添加后格式化的时间
	 * @Date: 2006-10-31
	 */
	public static String addDate(Date p_startDate, int p_count, int p_field, String p_format) throws ParseException {

		// 年，月，日、时，分，秒
		int l_year = getYearOfDate(p_startDate);
		int l_month = getMonthOfDate(p_startDate) - 1;
		int l_day = getDayOfDate(p_startDate);
		int l_hour = getHourOfDate(p_startDate);
		int l_minute = getMinuteOfDate(p_startDate);
		int l_second = getSecondOfDate(p_startDate);
		Calendar l_calendar = new GregorianCalendar(l_year, l_month, l_day, l_hour, l_minute, l_second);
		l_calendar.add(p_field, p_count);
		return toStrDateFromUtilDateByFormat(l_calendar.getTime(), p_format);
	}

	/**
	 * 计算两个日期之间相差的天数
	 * 
	 * @param smdate
	 *            较小的时间
	 * @param bdate
	 *            较大的时间
	 * @return 相差天数
	 * @throws ParseException
	 */
	public static int daysBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * 计算两个日期之间相差的小时数
	 * @param smdate  较小的时间
	 * @param bdate   较大的时间
	 * @return 相差小时数
	 * @throws ParseException
	 */
	public static int hoursBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_TIME);
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_hours = (time2 - time1) / (1000 * 3600);
		return Integer.parseInt(String.valueOf(between_hours));
	}
	public static Date truncateDay(Date date) {
		return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
	}

	public static Date addDay(Date currDate) {
		if (null == currDate)
			return new Date();
		return DateUtils.addDays(currDate, 1);
	}

	public static Date addDay(Date currDate, int day) {
		if (null == currDate)
			return new Date();
		return DateUtils.addDays(currDate, day);
	}

	public static Date addMonth(Date date) {
		if (null == date)
			return new Date();
		return DateUtils.addMonths(date, 1);
	}

	public static Date addMonth(Date date, int month) {
		if (null == date)
			return new Date();
		return DateUtils.addMonths(date, month);
	}

	public static Date getDayEnd(Date date) {
		if (null == date)
			return null;

		return parseDate(format(date, DATE) + " 23:59:59", DATE_TIME);
	}

	public static Date addMinutes(Date queryDate, Integer add) {
		return DateUtils.addMinutes(queryDate, add);
	}

	public static Date addHour(Date queryDate) {
		return addHour(queryDate, 1);
	}

	public static Date addHour(Date queryDate, Integer add) {
		return DateUtils.addHours(queryDate, add);
	}

	public static Integer getYear(Date queryDate) {
		Integer year = -1;
		if (null == queryDate) {
			return year;
		}
		String yearString = DateFormatUtils.format(queryDate, "yyyy");
		try {
			year = Integer.parseInt(yearString);
		} catch (Exception e) {
		}
		return year;
	}

	public static Integer getMonth(Date queryDate) {
		Integer mon = 1;
		if (null == queryDate) {
			return mon;
		}
		String monString = DateFormatUtils.format(queryDate, "MM");
		try {
			mon = Integer.parseInt(monString);
		} catch (Exception e) {
		}
		return mon;
	}

	public static Integer getDay(Date queryDate) {
		Integer day = 1;
		if (null == queryDate) {
			return day;
		}
		String dayString = DateFormatUtils.format(queryDate, "dd");
		try {
			day = Integer.parseInt(dayString);
		} catch (Exception e) {
		}
		return day;
	}

	public static String getWeekOfDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}

	public static String format(Date date, String dateFormat) {
		return DateFormatUtils.format(date, dateFormat);
	}

	public static Date parseDate(String strDate, String dateFormat) {
		if (null == strDate)
			return null;

		Date parseDate = null;
		try {
			parseDate = DateUtils.parseDate(strDate, new String[] { dateFormat });
		} catch (Exception e) {
			e.printStackTrace();
		}
		return parseDate;
	}

	public static String getDateNickName(Date date) {
		Date today = truncateDay(new Date());
		Date tomorrow = addDay(today);
		Date afterTom = addDay(tomorrow);
		Date now = truncateDay(date);
		if (now.getTime() == today.getTime())
			return "今天";
		if (now.getTime() == tomorrow.getTime())
			return "明天";
		if (now.getTime() == afterTom.getTime())
			return "后天";
		return getWeekOfDate(date);
	}

	public static Long timeDifference(Date dateStrat, Date dateEnd) {
		Long diff = dateStrat.getTime() - dateEnd.getTime();
		return diff;
	}

	public static Long secondDifference(Date dateStrat, Date dateEnd) {// 两个日期之间相差的秒数
		Long diff = (dateStrat.getTime() - dateEnd.getTime()) / 1000;
		return diff;
	}

	public static Long dayDifference(Date dateStrat, Date dateEnd) {// 两个日期之间相差的天数
		Long diff = (dateStrat.getTime() - dateEnd.getTime()) / 86400000;
		return diff;
	}

	public static String getDateByHour(Date dateStrat) {
		System.out.println("dateStrat" + dateStrat);
		int year = getYearOfDate(dateStrat);
		int month = getMonthOfDate(dateStrat);
		int day = getDayOfDate(dateStrat);
		int hour = getHourOfDate(dateStrat);
		System.out.println("year:" + year + "month" + month + "day" + day);
		String dateStr = year + "-" + month + "-" + day + " " + hour + ":00:00";
		System.out.println("dateStr:" + dateStr);
		return dateStr;

	}

	/**
	 * 日期转时间戳
	 * 
	 * @param date
	 * @return
	 */
	public static Long DateToTimeStemp(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.getTimeInMillis();
	}

	public static void main(String[] args) {
		// Date queryDate = DataUtil.strToDate("2015-04-13 10:02:12",
		// DATE_TIME);
		// System.out.println(DataUtil.dateToStrLong(queryDate));
		// Date date = parseDate("1972-02-01", DATE);
		// System.out.println(getLastDayOfMonth(date));
		// Date startTime = null;
		// try {
		// startTime = DateUtil.strToDate(DateUtil.addDate(new Date(), 1,
		// Calendar.HOUR, DateUtil.DATE_TIME));
		// } catch (ParseException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// startTime = DateUtil.strToDate(DateUtil.getDateByHour(startTime));
		// System.out.println("startTime:" + startTime);S
		// Long sleepTime = DateUtil.timeDifference(startTime, new Date());
		// System.out.println("sleepTime==>" + sleepTime);
		// String dateStr = "2015-04-06 00:00:00";
		// // 1437582189903
		// // Calendar cal = Calendar.getInstance();
		// // cal.setTime(new Date());
		// // long timestamp = cal.getTimeInMillis();
		// // String dd = timestampToDate(dateStr);
		//
		// Long dd = DateToTimestamp(strToDate(dateStr));
		// System.out.println("))))))))))" + dd);
		// dd = DateToTimestamp(new Date());
		// System.out.println("))))))))))" + dd);
		// // 1397577600
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		// String date = sdf.format(new Date(1270483200 * 1000));
		// System.out.println(date);
		// System.out.println(strToDate(dateStr).getTime() +
		// "rrrrrrrrrrrrrrrddddddddddddddddddddddddddddd"
		// + DateToTimeStemp(strToDate(dateStr)));

		// Date date1 = new Date();
		// Date date2 = DateUtil.strToDate("2015-07-31 23:59:59",
		// DateUtil.DATE_TIME);
		// Long expireSecond = DateUtil.secondDifference(date2, date1);
		// System.out.println(expireSecond);
		// System.out.println(DateUtil.timeDifference(date2, date1));
		// System.out.println(DateUtil.dayDifference(date2, date1));

		System.out.println(getDayOfDate(new Date()));
	}

	/**
	 * Date类型转换为10位时间戳
	 * 
	 * @param time
	 * @return
	 */
	public static Long DateToTimestamp(Date time) {
		Timestamp ts = new Timestamp(time.getTime());

		return (Long) ((ts.getTime()) / 1000);
	}

	/**
	 * 比较日期前后 date > date2 则返回 1 date < date2 则返回 -1 date = date2 则返回 0
	 * 
	 * @param date
	 * @param date2
	 * @return
	 */
	public static int compareDate(Date date, Date date2) {
		if (date.after(date2)) {
			return 1;
		}
		if (date.before(date2))
			return -1;

		return 0;
	}

}
